<template>
    <div class="chat-container">
        <div class="chat-header">
            <h1>聊天室</h1>
            <div class="user-count">在线人数: {{ userCount }}</div>
        </div>
        <div class="chat-messages" ref="messageContainer">
            <div v-if="!isLoadingMore" class="loading-more">
                <span>没有更多消息了！</span>
            </div>
            <div v-for="(message, index) in messages" :key="index" class="message-wrapper"
                :class="{ 'self-message-wrapper': message.isSelf }">
                <div class="message-container">
                    <img v-if="!message.isSelf" :src="message.fromAvatar" alt="用户头像" class="avatar" />
                    <div class="message-content-container">
                        <div class="message-header">
                            <span class="username" v-if="!message.isSelf">{{ message.fromUser }}</span>
                            <span v-if="!message.isSelf" class="timestamp">{{ message.time }}</span>
                            <span v-else class="timestamp2">{{ message.time }}</span>
                        </div>
                        <div v-if="message.type == 'text'" class="message-bubble"
                            :class="{ 'self-bubble': message.isSelf }">
                            <div class="message-content" v-html="message.content"></div>
                        </div>
                        <div v-else class="image-message" :class="{ 'self-image': message.isSelf }">
                            <img @click="openImageViewer(message.content)" class="message-image" :src="message.content"
                                alt="图片">
                        </div>
                    </div>
                    <img v-if="message.isSelf" :src="user.userAvatar || defaultAvatar" alt="我的头像" class="avatar" />
                </div>
            </div>
        </div>
        <el-dialog v-model="imageViewerVisible" style="text-align: center;" align-center @close="closeImageViewer">
            <img :src="currentImage" alt="大图预览" style="height: 700px">
        </el-dialog>
        <div class="chat-input">
            <div class="input-area">
                <input v-model="messageInput" @keyup.enter="sendMessage" placeholder="输入消息..." class="message-input">
                <div class="toolbar">
                    <!-- 阻止事件冒泡 -->
                    <button class="toolbar-button" @click.stop="toggleEmojiPanel">😀</button>
                    <el-upload style="font-size: 28px;padding: 0;" :show-file-list="false" :http-request="uploadFile"
                        :auto-upload="true" accept="image/*">📷</el-upload>
                </div>
                <button @click="sendMessage" class="send-button">发送</button>
            </div>
        </div>
        <!-- 表情面板 (增强版) -->
        <div ref="emojiPanelOuter" v-show="emojiPanelVisible" class="emoji-panel-outer">
            <div class="emoji-tabs">
                <button v-for="(category, categoryName) in emojiCategories" :key="categoryName"
                    :class="{ 'active': activeCategory === categoryName }" @click="activeCategory = categoryName">
                    {{ categoryName }}
                </button>
            </div>
            <div class="emoji-content">
                <div v-show="activeCategory === categoryName" v-for="(category, categoryName) in emojiCategories"
                    :key="categoryName">
                    <h3>{{ categoryName }}</h3>
                    <div class="emoji-grid">
                        <span v-for="emoji in category" :key="emoji" @click="insertEmoji(emoji)" class="emoji-item">{{
                            emoji }}</span>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import { jwtDecode } from 'jwt-decode';
import _axios from '../../utils/myAxios';
import { useRouter } from 'vue-router'

const router = useRouter()

// 扩展后的表情分类
const emojiCategories = ref({
    '常用': [
        '😊', '😄', '❤️', '😠', '😭', '😳', '😮', '😎', '🤔', '👌',
        '👍', '👎', '👏', '🙌', '🙏', '👐', '🤝', '👋', '✌️', '👊',
        '😏', '😉', '😁', '😔', '😴', '😀', '😢', '😡', '🤩', '😫'
    ],
    '动物': [
        '🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐨', '🐯',
        '🦁', '🐮', '🐷', '🐸', '🐵', '🐔', '🐧', '🐦', '🐤', '🦆'
    ],
    '食物': [
        '🍎', '🍐', '🍊', '🍋', '🍌', '🍉', '🍇', '🍓', '🍈', '🍒',
        '🍑', '🍍', '🥭', '🍅', '🥦', '🥬', '🍠', '🌽', '🍞', '🧀',
        '🍖', '🍗', '🍔', '🍟', '🌯', '🍕', '🥪', '🍳', '🥗', '🍝'
    ],
    '活动': [
        '🎮', '📱', '💻', '📺', '📷', '🎬', '🎨', '🎼', '🎸', '🎧',
        '📚', '✏️', '🎨', '🎯', '🚴', '🏊', '🏋️', '🎭', '🎪', '🎮'
    ],
    '旅行': [
        '🚗', '🚕', '🚙', '🚌', '🚎', '🏎️', '🚓', '🚑', '🚒', '✈️',
        '🚀', '⛵', '🚢', '🚁', '🚂', '🚄', '🚅', '🚃', '🚞', '🚇'
    ],
    '表情': [
        '😄', '😆', '😊', '😇', '😍', '🥰', '😛', '😜', '🤪', '😎',
        '🤓', '🧐', '😏', '😒', '😞', '😔', '😟', '😢', '😭', '😱',
        '😨', '😰', '😤', '😡', '🤬', '🥳', '🤩', '🥺', '🤗', '🤔'
    ],
    '物品': [
        '📱', '💻', '⌚', '📺', '📷', '📸', '🔋', '💡', '🔦', '🔌',
        '📧', '📨', '📩', '📫', '📬', '📭', '📮', '📯', '📰', '📓'
    ],
    '符号': [
        '❤️', '🧡', '💛', '💚', '💙', '💜', '🖤', '🤍', '🤎', '💕',
        '💞', '💓', '💗', '💖', '💘', '💝', '💟', '❣️', '💯',
        '✨', '⭐', '🌟', '💫', '💥', '💢', '🔥', '💦', '💧', '❄️'
    ]
})

const messages = ref([]);
const messageInput = ref('');
const userCount = ref(0);
const ws = ref(null);
const user = ref({});
const messageContainer = ref(null);
const emojiPanelVisible = ref(false);
const emojiPanelOuter = ref(null);
const activeCategory = ref('常用'); // 新增：当前激活的表情分类
const defaultAvatar = 'http://47.92.174.180:8080/profile/2025/04/11/7a49c4e3c0ab4b059b187a60eefb2cfa.jpg';
const imgUrl = ref("")

// 每次显示的消息数量，可根据需求调整
const pageSize = ref(20);
// 当前显示的页码
const pageNum = ref(1);
// 总的消息数量，用于判断是否还有更多消息可加载
const totalMessages = ref(0);
// 标记是否正在加载更多消息，避免重复请求
const isLoadingMore = ref(false);

const imageViewerVisible = ref(false);
const currentImage = ref('');

// 打开图片查看器
const openImageViewer = (src) => {
    currentImage.value = src;
    imageViewerVisible.value = true;
};

async function uploadFile(img) {
    let res = await _axios.post('/api/upload',
        {
            img: img.file
        },
        {
            headers: { 'Content-Type': 'multipart/form-data' },
        })
    if (res.data.code == 200) {
        ws.value.send(JSON.stringify({
            type: 'image',
            content: "http://47.92.174.180:8080" + res.data.data,
            fromId: user.value.userId,
            fromUser: user.value.nickname,
            fromAvatar: user.value.userAvatar || defaultAvatar,
        }));
    } else {
        ElMessage({
            showClose: true,
            message: "图片上传错误",
            type: 'error',
            appendTo: "#app",
        })
    }
}

// 插入表情到输入框
const insertEmoji = (emoji) => {
    messageInput.value = messageInput.value + emoji;
    emojiPanelVisible.value = false;
};

// 切换表情面板显示状态
const toggleEmojiPanel = () => {
    emojiPanelVisible.value = !emojiPanelVisible.value;
};

// 滚动到底部
const scrollToBottom = (behavior = 'smooth') => {
    nextTick(() => {
        if (messageContainer.value) {
            // 使用 requestAnimationFrame 确保在浏览器重绘后执行
            requestAnimationFrame(() => {
                messageContainer.value.scrollTo({
                    top: messageContainer.value.scrollHeight,
                    behavior: behavior
                });
            });
        }
    });
};

const handleClickOutside = (event) => {
    if (emojiPanelVisible.value && emojiPanelOuter.value && !emojiPanelOuter.value.contains(event.target)) {
        emojiPanelVisible.value = false;
    }
};

onMounted(() => {
    let token = localStorage.getItem('Authorization');
        if (!token) {
            router.push('/login');
        }
        const { Authorization } = JSON.parse(token);
        user.value = jwtDecode(Authorization);

        _axios.get(`/chatRoom/getChatRoom?pageNum=${pageNum.value}&pageSize=${pageSize.value}`)
            .then(res => {
                if (res.data.code === 200) {
                    totalMessages.value = res.data.data.total;
                    res.data.data.chatRooms.map(item => {
                        messages.value.push({
                            fromUser: item.fromUser,
                            content: item.content,
                            time: item.time,
                            isSelf: item.fromId === user.value.userId,
                            fromAvatar: item.fromAvatar || defaultAvatar,
                            type: item.type
                        });
                    });
                    scrollToBottom('auto');
                } else if (res.data.code === 401) {
                    router.push('/login')
                }
            })
    // 连接WebSocket服务器
    ws.value = new WebSocket('ws://47.92.174.180:8080/chatRoom?userId=' + user.value.userId);

    if (messageContainer.value) {
        messageContainer.value.addEventListener('scroll', handleScroll);
    }

    ws.value.onopen = () => {
        console.log('WebSocket连接已建立');
    };

    ws.value.onmessage = (event) => {
        const data = JSON.parse(event.data);
        switch (data.type) {
            case 'message':
                messages.value.push({
                    fromUser: data.chatRoom.fromUser || '未知用户',
                    content: data.chatRoom.content || '',
                    time: data.chatRoom.time || new Date().toLocaleTimeString(),
                    isSelf: data.chatRoom.fromId == user.value.userId,
                    fromAvatar: data.chatRoom.fromAvatar || defaultAvatar,
                    type: data.chatRoom.type
                });
                userCount.value = data.userCount;
                totalMessages.value++; // 有新消息时更新总消息数量
                scrollToBottom('auto');
                break;
            case 'userCount':
                userCount.value = data.userCount;
                break;
            case 'system':
                messages.value.push({
                    fromUser: '系统',
                    content: data.message,
                    time: new Date().toLocaleTimeString(),
                    isSelf: false,
                    fromAvatar: defaultAvatar
                });
                scrollToBottom();
                break;
        }
    };

    ws.value.onclose = () => {
        console.log('WebSocket连接已关闭');
        messages.value.push({
            fromUser: '系统提示',
            content: '与服务器的连接已断开',
            time: new Date().toLocaleTimeString(),
            isSelf: false,
            fromAvatar: defaultAvatar,
            type: "text"
        });
        scrollToBottom('auto');
    };

    ws.value.onerror = (error) => {
        console.error('WebSocket错误:', error);
    };

    document.addEventListener('click', handleClickOutside);
});

onUnmounted(() => {
    document.removeEventListener('click', handleClickOutside);
    if (ws.value) {
        ws.value.close();
    }
    if (messageContainer.value) {
        messageContainer.value.removeEventListener('scroll', handleScroll);
    }
});

const sendMessage = () => {
    if (messageInput.value.trim() === '') return;
    ws.value.send(JSON.stringify({
        type: 'text',
        content: messageInput.value,
        fromId: user.value.userId,
        fromUser: user.value.nickname,
        fromAvatar: user.value.userAvatar || defaultAvatar,
    }));

    messageInput.value = '';
};
// 监听滚动事件
const handleScroll = () => {
    if (messageContainer.value.scrollTop === 0 && !isLoadingMore.value && messages.value.length < totalMessages.value) {
        loadMoreMessages();
    }
};
// 加载更多消息
const loadMoreMessages = async () => {
    isLoadingMore.value = true;
    pageNum.value++;

    try {
        const res = await _axios.get(`/chatRoom/getChatRoom?pageNum=${pageNum.value}&pageSize=${pageSize.value}`);
        if (res.data.code === 200) {
            const oldScrollHeight = messageContainer.value.scrollHeight;
            const oldMessagesLength = messages.value.length;

            // 将新消息添加到数组开头
            const newMessages = res.data.data.chatRooms.map(item => ({
                fromUser: item.fromUser,
                content: item.content,
                time: item.time,
                isSelf: item.fromId === user.value.userId,
                fromAvatar: item.fromAvatar || defaultAvatar,
                type: item.type
            }));

            messages.value.unshift(...newMessages);
            // 保持滚动位置
            nextTick(() => {
                messageContainer.value.scrollTop = messageContainer.value.scrollHeight - oldScrollHeight;
            });
        }
    } catch (error) {
        console.error('加载更多消息失败:', error);
    } finally {
        isLoadingMore.value = false;
    }
};
</script>
<style scoped>
/* 基础样式 */
.chat-container {
    display: flex;
    flex-direction: column;
    height: 100%;
    max-width: 800px;
    margin: 0 auto;
    background-color: #f7f7f7;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.chat-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px;
    background-color: #fff;
    border-bottom: 1px solid #eee;
    font-size: 18px;
    font-weight: 600;
    color: #333;
}

.user-count {
    font-size: 14px;
    color: #888;
}

.loading-more {
    text-align: center;
    padding: 12px;
    font-size: 14px;
    color: #666;
    background-color: rgba(255, 255, 255, 0.8);
    border-radius: 8px;
    margin: 8px auto;
    width: fit-content;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

/* 消息区域 */
.chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 16px;
    background-color: #f0f0f0;
    height: calc(100vh - 200px);
    /* 确保这个计算值正确 */
    min-height: 300px;
    /* 添加以下属性确保正确渲染 */
    display: flex;
    flex-direction: column;
}

.message-wrapper {
    display: flex;
    margin-bottom: 16px;
    clear: both;
}

.self-message-wrapper {
    justify-content: flex-end;
}

.message-container {
    display: flex;
    align-items: flex-start;
    max-width: 80%;
}

.avatar {
    width: 40px;
    height: 40px;
    border-radius: 14%;
    object-fit: cover;
    margin: 0 8px;
    margin-top: 15px;
}

.message-content-container {
    flex: 1;
}

.message-header {
    display: flex;
    align-items: center;
    margin-bottom: 4px;
}

.username {
    font-size: 14px;
    color: #666;
    margin-right: 8px;
}

.timestamp {
    font-size: 12px;
    color: #999;
    margin-right: auto;
}

.timestamp2 {
    font-size: 12px;
    color: #999;
    margin-left: auto;
}

.message-bubble {
    position: relative;
    padding: 10px 14px;
    border-radius: 12px;
    font-size: 16px;
    line-height: 1;
    max-width: 100%;
}

.message-bubble::before {
    content: '';
    position: absolute;
    top: 12px;
    width: 0;
    height: 0;
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
}

/* 对方消息气泡样式 */
.message-bubble:not(.self-bubble) {
    background-color: #fff;
    margin-left: 8px;
}

.message-bubble:not(.self-bubble)::before {
    left: -12px;
    border-right: 12px solid #fff;
}

/* 自己消息气泡样式 */
.self-bubble {
    background-color: #95ec69;
    margin-right: 8px;
}

.self-bubble::before {
    right: -12px;
    border-left: 12px solid #95ec69;
}

.image-message {
    max-width: 40%;
    margin: 8px 0;
}

.self-image {
    margin-left: auto;
}

.message-image {
    max-width: 100%;
    max-height: 300px;
    border-radius: 8px;
    object-fit: contain;
    display: block;
}

.message-content {
    word-wrap: break-word;
}

/* 输入区域 */
.chat-input {
    display: flex;
    padding: 12px 16px;
    background-color: #fff;
    border-top: 1px solid #eee;
}

.input-area {
    flex: 1;
    display: flex;
    flex-direction: column;
}

.message-input {
    padding: 10px 14px;
    border: 1px solid #ddd;
    border-radius: 20px;
    outline: none;
    font-size: 16px;
    resize: none;
}

.toolbar {
    display: flex;
    gap: 8px;
    margin-bottom: 10px;
}

.toolbar-button {
    margin-top: 7px;
    background: none;
    border: none;
    font-size: 25px;
    cursor: pointer;
    color: #666;
}

.send-button {
    padding: 10px 16px;
    background-color: #07c160;
    color: white;
    border: none;
    border-radius: 20px;
    cursor: pointer;
    font-size: 16px;
    margin-left: 12px;
    white-space: nowrap;
}

.send-button:hover {
    background-color: #06b056;
}

/* 表情面板增强版样式 */
.emoji-panel-outer {
    position: fixed;
    bottom: 100px;
    left: 50%;
    transform: translateX(-50%);
    width: 800px;
    max-width: 90%;
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
    padding: 0;
    z-index: 100;
    overflow: hidden;
}

.emoji-tabs {
    display: flex;
    border-bottom: 1px solid #eee;
    padding: 8px;
}

.emoji-tabs button {
    background: none;
    border: none;
    padding: 8px 12px;
    margin: 0 4px;
    border-radius: 4px;
    font-size: 14px;
    cursor: pointer;
    transition: background-color 0.2s;
}

.emoji-tabs button.active {
    background-color: #e6f7ff;
    color: #1890ff;
}

.emoji-content {
    padding: 16px;
    max-height: 300px;
    overflow-y: auto;
}

.emoji-grid {
    display: grid;
    grid-template-columns: repeat(10, 1fr);
    gap: 8px;
}

.emoji-item {
    font-size: 20px;
    text-align: center;
    padding: 8px;
    cursor: pointer;
    border-radius: 4px;
    transition: background-color 0.2s;
}

.emoji-item:hover {
    background-color: #f0f0f0;
}

/* 加载更多提示样式 */
.loading-more {
    text-align: center;
    padding: 10px;
    font-size: 14px;
    color: #666;
}
</style>